package com.yunkai.plate_lpr;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Message;
import android.util.Base64;
import android.util.Log;
import android.widget.ImageView;


import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.concurrent.Semaphore;

import com.hyperai.hyperlpr3.HyperLPR3;
import com.hyperai.hyperlpr3.bean.HyperLPRParameter;
import com.hyperai.hyperlpr3.bean.Plate;

public class SimpleRecog implements Runnable {

    private Semaphore Lock = new Semaphore(1);//以防止在关闭相机之前应用程序退出
    private boolean run = true;
//    private CraREActivity craREActivity;
    private WeakReference<CraREActivity> activityRef;

    private CameraUtil cameraUtil;
    private Thread simthread;
    private boolean DETENTY = false;//是否最后一次识别后退出

    private long handle;//算法句柄
    private static final String TAG = "车牌识别结果：";
     SimpleRecog(CraREActivity craREActivity, CameraUtil cameraUtil, ImageView imageview) {
//        this.craREActivity = craREActivity;
        this.activityRef = new WeakReference<>(craREActivity);

         this.cameraUtil = cameraUtil;
        simthread = new Thread(this);
        //simthread.setPriority(4);
        simthread.start();
        Log.i("线程",simthread.getPriority()+"");
    }

    @Override
    public void run() {
        try {
            Lock.acquire();
            initRecognizer();
            while (run && !Thread.interrupted()) { // 增加中断检查
                Bitmap[] bitmapArr = cameraUtil.getBitmap();
                if (bitmapArr != null) {
                    // 增加休眠避免空轮询
                    Thread.sleep(50);
                    Recog(bitmapArr, DETENTY);
                }
            }
        } catch (InterruptedException e) {
            Log.i("检测线程", "线程被中断");
        } finally {
            Lock.release();
            // 强制回收资源
            if (cameraUtil != null) {
                cameraUtil.onDestroy();
            }
            Log.e("检测线程", "结束");
        }
    }


    public void setDETENTY(boolean b){
        DETENTY = b;
    }

//    public void stop(){
//       this.run = false;
//    }
    public void stop(){
    this.run = false;
    if (simthread != null) {
        simthread.interrupt(); // 中断线程的阻塞状态
    }
}



      private int ennum = 0;
      private final int maxsize = 2;
      private String preplate = null;
      private void Recog(Bitmap[] bitmapArr,boolean lastdec ) {
          final CraREActivity craREActivity = activityRef.get();
        Bitmap bmp = bitmapArr[1];
        try {
            String res="error";
            if(lastdec){
                run = false;
                craREActivity.setBitmap(bmp);
                Message msg1 = new Message();
                msg1.what = 3;
                craREActivity.getHandler().sendMessage(msg1);
                String xcpath = ImageUtil.saveImage(craREActivity,bitmapArr[1]);
                sendmessage(res,xcpath,lastdec);
                return;
            }
            Bitmap rgba = bmp.copy(Bitmap.Config.ARGB_8888, true);
            int width = rgba.getWidth();
            int height = rgba.getHeight();
            byte[] imageData = getPixelsRGBA(rgba);
            long sttime = System.currentTimeMillis();
//              res =PlateRecognition.bitPlatecorr(imageDate,width,height,handle);
            Plate[] plates = HyperLPR3.getInstance().plateRecognition(imageData, height, width, HyperLPR3.CAMERA_ROTATION_0, HyperLPR3.STREAM_RGBA);
            Log.i("检测识别耗时","图片高："+height+"，宽："+width+""+ (System.currentTimeMillis()-sttime)+"ms");
            for (Plate plate : plates) {
                Log.i(TAG,  "" + plate.toString());
                //置信度大于0.9才相信
                if(plate.getType() != HyperLPR3.PLATE_TYPE_UNKNOWN && plate.getConfidence() > 0.9){
                    res = plate.getCode();
                }
            }
            if(!run){
                return;
            }
            if (!res.equals("error") || lastdec) {
                if(preplate == null){
                    preplate = res;
                    ennum = 1;
                    return;
                }else{
                    if(preplate.equals(res)){
                        preplate = res;
                        ennum++;
                    }else{
                        preplate = res;
                        ennum = 1;
                        return;
                    }
                }
                if(ennum >= maxsize){
                    run = false;
                    String xcpath = ImageUtil.saveImage(craREActivity,bitmapArr[0]);
                    sendmessage(res,xcpath,lastdec);
                }
            }
        }catch (Exception e){
            Log.e("车牌识别异常",e.getMessage());
        }finally {
            // 回收不再使用的 Bitmap
//            if (bitmapArr[0] != null && !bitmapArr[0].isRecycled()) {
//                bitmapArr[0].recycle();
//            }
//            if (bitmapArr[1] != null && !bitmapArr[1].isRecycled()) {
//                bitmapArr[1].recycle();
//            }
        }
    }

    public String bitmapToBase64(Bitmap bitmap) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
        byte[] byteArray = byteArrayOutputStream.toByteArray();
        return Base64.encodeToString(byteArray, Base64.DEFAULT);
    }

    private byte[] getPixelsRGBA(Bitmap image) {
        // calculate how many bytes our image consists of
        int bytes = image.getByteCount();
        ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
        image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer
        byte[] temp = buffer.array(); // Get the underlying array containing the

        return temp;
    }

    private void sendmessage(String res,String path,boolean lastdec){
            final CraREActivity craREActivity = activityRef.get();
        Message msg = new Message();
        msg.what = 1;
        Bundle bundle = new Bundle();
        bundle.putString("plate",res);
        bundle.putString("path",path);
        bundle.putString("online",lastdec?"true":"false");
        msg.setData(bundle);
        craREActivity.getHandler().sendMessage(msg);

    }



    public void onDestroy(){
        try {
            run = false;
            Lock.acquire();
            activityRef = null;
            cameraUtil = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            Lock.release();
        }
        Log.e("检测","结束");
    }






    // Load a network.
    public void initRecognizer() {
//      String proto1 = getmodelPath("l1.prototxt", craREActivity);
//      String weights1 = getmodelPath("l1_v2.caffemodel", craREActivity);
//      String proto2 = getmodelPath("l2.prototxt", craREActivity);
//      String weights2 = getmodelPath("l2_v2.caffemodel", craREActivity);
//      String ocr_weight = getmodelPath("v617_99_65.onnx", craREActivity);
//      handle = PlateRecognition.InitPlateRecognizer(proto1,weights1,proto2,weights2,ocr_weight);

        Log.i(TAG, "Network loaded successfully");
    }




}
